package com.molichuxing.services.infrastructure.service;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.service.RootService;
import com.molichuxing.services.infrastructure.dto.request.create.OrderScheduleDealerCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.OrderScheduleUserCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.OrderPayModifyDto;
import com.molichuxing.services.infrastructure.dto.request.modify.OrderSchedulePayableDateModifyDto;
import com.molichuxing.services.infrastructure.dto.request.modify.OrderScheduleRepaymentModifyDto;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.property.OrderScheduleStatusEnum;
import com.molichuxing.services.property.OrderTypeEnum;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * 订单排期基础服务
 *
 * @author zoumingyu
 * @date 2019年8月14日
 */
public interface OrderScheduleService extends RootService {

    /**
     * id查询订单排期信息
     *
     * @param id 排期id
     * @return
     */
    OrderScheduleDto getOrderSchedule(Integer id);

    /**
     * 查询订单排期信息
     *
     * @param orderCode 订单号
     * @return
     */
    List<OrderScheduleDto> getOrderSchedule(Long orderCode);

    /**
     * 查询订单排期信息
     *
     * @param orderCode           订单号
     * @param orderScheduleStatus 订单排期状态枚举
     * @return
     */
    List<OrderScheduleDto> getOrderSchedule(Long orderCode, OrderScheduleStatusEnum orderScheduleStatus);

    /**
     * 查询专属里程订单本期排期
     *
     * @param params orderCode 订单号-long
     *               userIds   用户id(查询C端用户订单排期)-list
     * @return
     * @throws Exception
     */
    Paged<OrderScheduleCurrentPeriodDto> getExclusivelOrderCurrentPeriod(Map<String, Object> params, int pageNum,
                                                                         int pageSize) throws Exception;

    /**
     * 查询专属里程订单逾期未还排期
     *
     * @param params orderCode 订单号-long
     *               userIds   用户id(查询C端用户订单排期)-list
     * @return
     * @throws Exception
     */
    Paged<OrderScheduleOverdueDto> getExclusivelOrderOverdue(Map<String, Object> params, int pageNum,
                                                             int pageSize) throws Exception;

    /**
     * 是否存在逾期未还订单
     *
     * @param orderCode 订单号
     * @return
     */
    Boolean getIsOverdue(Long orderCode);

    /**
     * 查询经销商订单本期排期
     *
     * @param params orderCode 订单号-long
     *               dealerIds 经销商id(查询经销商订单排期)-list
     * @return
     * @throws Exception
     */
    Paged<OrderScheduleCurrentPeriodDto> getDealerOrderCurrentPeriod(Map<String, Object> params, int pageNum,
                                                                     int pageSize) throws Exception;

    /**
     * 查询经销商订单逾期未还排期
     *
     * @param params orderCode 订单号-long
     *               dealerIds 经销商id(查询经销商订单排期)-list
     * @return
     * @throws Exception
     */
    Paged<OrderScheduleOverdueDto> getDealerOrderOverdue(Map<String, Object> params, int pageNum, int pageSize)
            throws Exception;

    /**
     * 查询本期排期
     *
     * @param params    orderCode：订单号-long <br/>
     *                  userIds：用户id(查询C端用户订单排期)-list <br/>
     *                  dealerIds：经销商id(查询经销商订单排期)-list
     * @param orderType 订单类型枚举-enum
     * @param pageNum   页数
     * @param pageSize  每页条数
     * @return
     * @throws Exception
     */
    Paged<OrderScheduleCurrentPeriodDto> getCurrentPeriod(Map<String, Object> params, OrderTypeEnum orderType,
                                                          int pageNum, int pageSize) throws Exception;

    /**
     * 查询逾期未还排期
     *
     * @param params    orderCode：订单号-long <br/>
     *                  userIds：用户id(查询C端用户订单排期)-list <br/>
     *                  dealerIds：经销商id(查询经销商订单排期)-list
     * @param orderType 订单类型枚举-enum
     * @param pageNum   页数
     * @param pageSize  每页条数
     * @return
     * @throws Exception
     */
    Paged<OrderScheduleOverdueDto> getOverdue(Map<String, Object> params, OrderTypeEnum orderType, int pageNum,
                                              int pageSize) throws Exception;

    /**
     * 获取逾期订单总数
     *
     * @param orderType 订单类型
     * @return
     */
    int getOverdueTotal(OrderTypeEnum orderType) throws Exception;

    /**
     * 统计排期信息
     *
     * @param orderCode 订单号
     * @return
     */
    OrderScheduleStatisticsDto getScheduleStatistics(Long orderCode);

    /**
     * 新增用户排期信息
     *
     * @param createDto
     * @return true：成功，false：失败
     */
    Boolean createUserOrderSchedule(OrderScheduleUserCreateDto createDto);

    /**
     * 新增经销商排期信息
     *
     * @param createDto
     * @return true：成功，false：失败
     */
    Boolean createDealerOrderSchedule(OrderScheduleDealerCreateDto createDto);

    /**
     * 根据还款计划id查询还款信息
     *
     * @param ids 还款计划id
     * @return
     */
    List<OrderScheduleDto> getOrderScheduleDtoListById(List<Integer> ids);


    /**
     * 获取经销商下未所有还款订单
     *
     * @param dealerId
     * @return
     */
    List<OrderScheduleUnpaidDto> getOrderScheduleUnpaidByDealerId(Integer dealerId);


    /**
     * 查询还款关联信息
     *
     * @param orderCode
     * @return
     */
    List<OrderScheduleRelationDto> getOrderScheduleRelationDto(Long orderCode);


    /**
     * 根据还款计划id查询经销商订单还款信息
     *
     * @param ids 还款计划id
     * @return
     */
    List<OrderScheduleDto> getOrderDealerListByIds(List<Integer> ids);


    /**
     * 根据订单号查询首付款金额
     *
     * @param orderCode
     * @return
     */
    BigDecimal getDownPaymentByOrderCode(Long orderCode);


    /**
     * 根据订单号查询已付款金额
     *
     * @param orderCode
     * @return
     */
    BigDecimal getAmountPaidByOrderCode(Long orderCode, Integer status);

    /**
     * 还款成功修改排期信息
     *
     * @param modifyDto
     * @return
     * @throws BizException
     */
    Boolean modifyOrderScheduleRepayment(OrderScheduleRepaymentModifyDto modifyDto) throws BizException;

    /**
     * 修改经销商订单排期应付款日期
     *
     * @param modifyDto
     * @return
     * @throws BizException
     */
    Boolean modifyDealerOrderSchedulePayableDate(OrderSchedulePayableDateModifyDto modifyDto)
            throws BizException;

    /**
     * 修改经销商订单排期应付款日期
     *
     * @param modifyDtoList
     * @return
     * @throws BizException
     */
    Boolean modifyDealerOrderSchedulePayableDate(List<OrderSchedulePayableDateModifyDto> modifyDtoList)
            throws BizException;


    /**
     * 还款计划数量
     *
     * @return
     */
    Integer getOrderScheduleCurrentPeriodCount(Integer dealerId);

    /**
     * 逾期数量
     *
     * @return
     */
    Integer getOrderScheduleOverdueCount(Integer dealerId);

    /**
     * 获取采购单第一期应付金额
     */
    BigDecimal getDealerFirstPayable(Long orderCode);


    /**
     * 获取采购单应付金额
     */
    BigDecimal getDealerPayable(Long orderCode);

    /**
     * 查询订单排期信息
     *
     * @param orderCode 订单号
     * @param periods   期数
     * @return
     */
    OrderScheduleDto getOrderScheduleByPeriods(Long orderCode, Integer periods);

    /**
     * 支付完成修改排期信息
     *
     * @param modifyDto
     * @return
     */
    Boolean modifyPay(OrderPayModifyDto modifyDto);

    /**
     * 根据经销商id查询是否存在未还款的订单
     *
     * @param dealerId
     * @return
     */
    Integer getDealerByDealerId(Integer dealerId);


    /**
     * 根据id修改排期状态
     *
     * @param id
     * @return
     */
    int modifyStatusByIdAndOrderCode(Integer id, Integer status, Integer payWay);

    /**
     * 逾期未还订单数量
     */
    Integer getOrderOverdue();

    /**
     * 专属订单未还排期
     *
     * @param payableDate
     * @param isAll       true:查询<payableDate，false：查询=payableDate
     * @return
     */
    List<OrderScheduleDto> getExclusivelUnpayPeriod(LocalDate payableDate, boolean isAll);

    /**
     * 商家订单未还排期
     *
     * @param payableDate
     * @param isAll       true:查询<payableDate，false：查询=payableDate
     * @return
     */
    List<OrderScheduleDto> getDealerUnpayPeriod(LocalDate payableDate, boolean isAll);

    /**
     * 排期修改为已终止
     *
     * @param orderCode 订单号
     * @return
     */
    boolean modifyCancel(Long orderCode);

    /**
     * 排期修改为已终止
     *
     * @param orderCode           订单号
     * @param orderScheduleStatus 取消前状态
     * @return
     */
    boolean modifyCancel(Long orderCode, OrderScheduleStatusEnum orderScheduleStatus);

    /**
     * 查询专属里程本期还款计划导出数据
     *
     * @param selectParams
     * @return
     */
    List<OrderScheduleCurrentPeriodDto> getExclusivelOrderCurrentPeriodDownload(
            Map<String, Object> selectParams);

    /**
     * 查询专属里程本期还款计划导出数据条数
     *
     * @param selectParams
     * @return
     */
    Long getExclusivelOrderCurrentPeriodDownloadCount(Map<String, Object> selectParams);

    /**
     * 查询专属里程逾期数据导出数据
     *
     * @param selectParams
     * @return
     */
    List<OrderScheduleOverdueDto> getExclusivelOrderOverdueDownload(Map<String, Object> selectParams);

    /**
     * 查询专属里程逾期数据导出数据条数
     *
     * @param selectParams
     * @return
     */
    Long getExclusivelOrderOverdueDownloadCount(Map<String, Object> selectParams);

    /**
     * 查询应还日期小于查询日期的有效排期信息(未还、已还)
     *
     * @param userId      用户id
     * @param payableDate 查询日期
     * @return
     */
    List<OrderScheduleDto> getOrderScheduleLtDate(Integer userId, LocalDate payableDate);

    /**
     * 查询排期信息
     *
     * @param scheduleIds 排期ids
     * @return
     */
    Map<Integer, OrderScheduleDto> getOrderSchedule(List<Integer> scheduleIds);
}
